home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / glibc-1.09 / glibc-1 / glibc-1.09.1 / resolv / gethnamaddr.c next >
Encoding:
C/C++ Source or Header  |  1994-07-28  |  16.3 KB  |  706 lines

  1. /*
  2.  * ++Copyright++ 1985, 1988, 1993
  3.  * -
  4.  * Copyright (c) 1985, 1988, 1993
  5.  *    The Regents of the University of California.  All rights reserved.
  6.  * 
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 2. Redistributions in binary form must reproduce the above copyright
  13.  *    notice, this list of conditions and the following disclaimer in the
  14.  *    documentation and/or other materials provided with the distribution.
  15.  * 3. All advertising materials mentioning features or use of this software
  16.  *    must display the following acknowledgement:
  17.  *     This product includes software developed by the University of
  18.  *     California, Berkeley and its contributors.
  19.  * 4. Neither the name of the University nor the names of its contributors
  20.  *    may be used to endorse or promote products derived from this software
  21.  *    without specific prior written permission.
  22.  * 
  23.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  24.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  27.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  28.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  29.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  30.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  31.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  32.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  33.  * SUCH DAMAGE.
  34.  * -
  35.  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
  36.  * 
  37.  * Permission to use, copy, modify, and distribute this software for any
  38.  * purpose with or without fee is hereby granted, provided that the above
  39.  * copyright notice and this permission notice appear in all copies, and that
  40.  * the name of Digital Equipment Corporation not be used in advertising or
  41.  * publicity pertaining to distribution of the document or software without
  42.  * specific, written prior permission.
  43.  * 
  44.  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  45.  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  46.  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
  47.  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  48.  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  49.  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  50.  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  51.  * SOFTWARE.
  52.  * -
  53.  * --Copyright--
  54.  */
  55.  
  56. #if defined(LIBC_SCCS) && !defined(lint)
  57. static char sccsid[] = "@(#)gethostnamadr.c    8.1 (Berkeley) 6/4/93";
  58. static char rcsid[] = "$Id: gethnamaddr.c,v 1.3 1994/07/28 21:50:33 roland Exp $";
  59. #endif /* LIBC_SCCS and not lint */
  60.  
  61. #include <sys/param.h>
  62. #include <sys/socket.h>
  63. #include <netinet/in.h>
  64. #include <arpa/inet.h>
  65. #include <arpa/nameser.h>
  66.  
  67. #include <stdio.h>
  68. #include <netdb.h>
  69. #include <resolv.h>
  70. #include <ctype.h>
  71. #include <errno.h>
  72. #include <syslog.h>
  73.  
  74. #ifndef LOG_AUTH
  75. # define LOG_AUTH 0
  76. #endif
  77.  
  78. #define MULTI_PTRS_ARE_ALIASES 1    /* XXX - experimental */
  79.  
  80. #if defined(BSD) && (BSD >= 199103)
  81. # include <string.h>
  82. #else
  83. # include "../conf/portability.h"
  84. #endif
  85. #if defined(USE_OPTIONS_H)
  86. # include <../conf/options.h>
  87. #endif
  88.  
  89. #define    MAXALIASES    35
  90. #define    MAXADDRS    35
  91.  
  92. static const char AskedForGot[] =
  93.               "gethostby*.getanswer: asked for \"%s\", got \"%s\"";
  94.  
  95. static char *h_addr_ptrs[MAXADDRS + 1];
  96.  
  97. static struct hostent host;
  98. static char *host_aliases[MAXALIASES];
  99. static char hostbuf[8*1024];
  100. static struct in_addr host_addr;
  101. static FILE *hostf = NULL;
  102. static int stayopen = 0;
  103.  
  104. #ifdef RESOLVSORT
  105. static void addrsort __P((char **, int));
  106. #endif
  107.  
  108. #if PACKETSZ > 1024
  109. #define    MAXPACKET    PACKETSZ
  110. #else
  111. #define    MAXPACKET    1024
  112. #endif
  113.  
  114. typedef union {
  115.     HEADER hdr;
  116.     u_char buf[MAXPACKET];
  117. } querybuf;
  118.  
  119. typedef union {
  120.     int32_t al;
  121.     char ac;
  122. } align;
  123.  
  124. extern int h_errno;
  125.  
  126. static struct hostent *
  127. getanswer(answer, anslen, qname, qclass, qtype)
  128.     const querybuf *answer;
  129.     int anslen;
  130.     const char *qname;
  131.     int qclass, qtype;
  132. {
  133.     register const HEADER *hp;
  134.     register const u_char *cp;
  135.     register int n;
  136.     const u_char *eom;
  137.     char *bp, **ap, **hap;
  138.     int type, class, buflen, ancount, qdcount;
  139.     int haveanswer, had_error;
  140.     int toobig = 0;
  141.     char tbuf[MAXDNAME+1];
  142.  
  143.     host.h_name = NULL;
  144.     eom = answer->buf + anslen;
  145.     /*
  146.      * find first satisfactory answer
  147.      */
  148.     hp = &answer->hdr;
  149.     ancount = ntohs(hp->ancount);
  150.     qdcount = ntohs(hp->qdcount);
  151.     bp = hostbuf;
  152.     buflen = sizeof hostbuf;
  153.     cp = answer->buf + HFIXEDSZ;
  154.     if (qdcount != 1) {
  155.         h_errno = NO_RECOVERY;
  156.         return (NULL);
  157.     }
  158.     if ((n = dn_expand(answer->buf, eom, cp, bp, buflen)) < 0) {
  159.         h_errno = NO_RECOVERY;
  160.         return (NULL);
  161.     }
  162.     cp += n + QFIXEDSZ;
  163.     if (qtype == T_A) {
  164.         /* res_send() has already verified that the query name is the
  165.          * same as the one we sent; this just gets the expanded name
  166.          * (i.e., with the succeeding search-domain tacked on).
  167.          */
  168.         n = strlen(bp) + 1;        /* for the \0 */
  169.         host.h_name = bp;
  170.         bp += n;
  171.         buflen -= n;
  172.         /* The qname can be abbreviated, but h_name is now absolute. */
  173.         qname = host.h_name;
  174.     }
  175.     ap = host_aliases;
  176.     *ap = NULL;
  177.     host.h_aliases = host_aliases;
  178.     hap = h_addr_ptrs;
  179.     *hap = NULL;
  180. #if BSD >= 43 || defined(h_addr)    /* new-style hostent structure */
  181.     host.h_addr_list = h_addr_ptrs;
  182. #endif
  183.     haveanswer = 0;
  184.     had_error = 0;
  185.     while (ancount-- > 0 && cp < eom && !had_error) {
  186.         n = dn_expand(answer->buf, eom, cp, bp, buflen);
  187.         if (n < 0) {
  188.             had_error++;
  189.             continue;
  190.         }
  191.         cp += n;            /* name */
  192.         type = _getshort(cp);
  193.          cp += INT16SZ;            /* type */
  194.         class = _getshort(cp);
  195.          cp += INT16SZ + INT32SZ;    /* class, TTL */
  196.         n = _getshort(cp);
  197.         cp += INT16SZ;            /* len */
  198.         if (class != qclass) {
  199.             /* XXX - debug? syslog? */
  200.             cp += n;
  201.             continue;        /* XXX - had_error++ ? */
  202.         }
  203.         if (qtype == T_A && type == T_CNAME) {
  204.             if (ap >= &host_aliases[MAXALIASES-1])
  205.                 continue;
  206.             n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
  207.             if (n < 0) {
  208.                 had_error++;
  209.                 continue;
  210.             }
  211.             cp += n;
  212.             if (host.h_name && strcasecmp(host.h_name, bp) != 0) {
  213.                 syslog(LOG_NOTICE|LOG_AUTH,
  214.         "gethostby*.getanswer: asked for \"%s\", got CNAME for \"%s\"",
  215.                        host.h_name, bp);
  216.                 continue;    /* XXX - had_error++ ? */
  217.             }
  218.             /* Store alias. */
  219.             *ap++ = bp;
  220.             n = strlen(bp) + 1;    /* for the \0 */
  221.             bp += n;
  222.             buflen -= n;
  223.             /* Get canonical name. */
  224.             n = strlen(tbuf) + 1;    /* for the \0 */
  225.             if (n > buflen) {
  226.                 had_error++;
  227.                 continue;
  228.             }
  229.             strcpy(bp, tbuf);
  230.             host.h_name = bp;
  231.             bp += n;
  232.             buflen -= n;
  233.             continue;
  234.         }
  235.         if (type != qtype) {
  236.             syslog(LOG_NOTICE|LOG_AUTH,
  237.              "gethostby*.getanswer: asked for type %d(%s), got %d(%s)",
  238.                    qtype, qname, type, bp);
  239.             cp += n;
  240.             continue;        /* XXX - had_error++ ? */
  241.         }
  242.         switch (type) {
  243.         case T_PTR:
  244.             if (strcasecmp(qname, bp) != 0) {
  245.                 syslog(LOG_NOTICE|LOG_AUTH,
  246.                        AskedForGot, qname, bp);
  247.                 cp += n;
  248.                 continue;    /* XXX - had_error++ ? */
  249.             }
  250.             n = dn_expand(answer->buf, eom, cp, bp, buflen);
  251.             if (n < 0) {
  252.                 had_error++;
  253.                 break;
  254.             }
  255. #if MULTI_PTRS_ARE_ALIASES
  256.             cp += n;
  257.             if (!haveanswer)
  258.                 host.h_name = bp;
  259.             else if (ap < &host_aliases[MAXALIASES-1])
  260.                 *ap++ = bp;
  261.             else
  262.                 n = -1;
  263.             if (n != -1) {
  264.                 n = strlen(bp) + 1;    /* for the \0 */
  265.                 bp += n;
  266.                 buflen -= n;
  267.             }
  268.             break;
  269. #else
  270.             host.h_name = bp;
  271.             return (&host);
  272. #endif
  273.         case T_A:
  274.             if (strcasecmp(host.h_name, bp) != 0) {
  275.                 syslog(LOG_NOTICE|LOG_AUTH,
  276.                        AskedForGot, host.h_name, bp);
  277.                 cp += n;
  278.                 continue;    /* XXX - had_error++ ? */
  279.             }
  280.             if (haveanswer) {
  281.                 if (n != host.h_length) {
  282.                     cp += n;
  283.                     continue;
  284.                 }
  285.             } else {
  286.                 register int nn;
  287.  
  288.                 host.h_length = n;
  289.                 host.h_addrtype = (class == C_IN)
  290.                           ? AF_INET
  291.                           : AF_UNSPEC;
  292.                 host.h_name = bp;
  293.                 nn = strlen(bp) + 1;    /* for the \0 */
  294.                 bp += nn;
  295.                 buflen -= nn;
  296.             }
  297.  
  298.             bp += sizeof(align) - ((u_long)bp % sizeof(align));
  299.  
  300.             if (bp + n >= &hostbuf[sizeof hostbuf]) {
  301. #ifdef DEBUG
  302.                 if (_res.options & RES_DEBUG)
  303.                     printf("size (%d) too big\n", n);
  304. #endif
  305.                 had_error++;
  306.                 continue;
  307.             }
  308.             if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
  309.                 if (_res.options & RES_DEBUG && !toobig++)
  310.                     printf("Too many addresses (%d)\n",
  311.                            MAXADDRS);
  312.                 cp += n;
  313.                 continue;
  314.             }
  315.             bcopy(cp, *hap++ = bp, n);
  316.             bp += n;
  317.             cp += n;
  318.             break;
  319.         default:
  320.             abort();
  321.         } /*switch*/
  322.         if (!had_error)
  323.             haveanswer++;
  324.     } /*while*/
  325.     if (haveanswer) {
  326.         *ap = NULL;
  327.         *hap = NULL;
  328. # if defined(RESOLVSORT)
  329.         /*
  330.          * Note: we sort even if host can take only one address
  331.          * in its return structures - should give it the "best"
  332.          * address in that case, not some random one
  333.          */
  334.         if (_res.nsort && haveanswer > 1 &&
  335.             qclass == C_IN && qtype == T_A)
  336.             addrsort(h_addr_ptrs, haveanswer);
  337. # endif /*RESOLVSORT*/
  338. #if BSD >= 43 || defined(h_addr)    /* new-style hostent structure */
  339.         /* nothing */
  340. #else
  341.         host.h_addr = h_addr_ptrs[0];
  342. #endif /*BSD*/
  343.         if (!host.h_name) {
  344.             n = strlen(qname) + 1;    /* for the \0 */
  345.             strcpy(bp, qname);
  346.             host.h_name = bp;
  347.         }
  348.         return (&host);
  349.     } else {
  350.         h_errno = TRY_AGAIN;
  351.         return (NULL);
  352.     }
  353. }
  354.  
  355. struct hostent *
  356. gethostbyname(name)
  357.     const char *name;
  358. {
  359.     querybuf buf;
  360.     register const char *cp;
  361.     int n;
  362.     extern struct hostent *_gethtbyname();
  363.  
  364.     /*
  365.      * disallow names consisting only of digits/dots, unless
  366.      * they end in a dot.
  367.      */
  368.     if (isdigit(name[0]))
  369.         for (cp = name;; ++cp) {
  370.             if (!*cp) {
  371.                 if (*--cp == '.')
  372.                     break;
  373.                 /*
  374.                  * All-numeric, no dot at the end.
  375.                  * Fake up a hostent as if we'd actually
  376.                  * done a lookup.
  377.                  */
  378.                 if (!inet_aton(name, &host_addr)) {
  379.                     h_errno = HOST_NOT_FOUND;
  380.                     return (NULL);
  381.                 }
  382.                 host.h_name = (char *)name;
  383.                 host.h_aliases = host_aliases;
  384.                 host_aliases[0] = NULL;
  385.                 host.h_addrtype = AF_INET;
  386.                 host.h_length = INT32SZ;
  387.                 h_addr_ptrs[0] = (char *)&host_addr;
  388.                 h_addr_ptrs[1] = NULL;
  389. #if BSD >= 43 || defined(h_addr)    /* new-style hostent structure */
  390.                 host.h_addr_list = h_addr_ptrs;
  391. #else
  392.                 host.h_addr = h_addr_ptrs[0];
  393. #endif
  394.                 return (&host);
  395.             }
  396.             if (!isdigit(*cp) && *cp != '.') 
  397.                 break;
  398.         }
  399.  
  400.     if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof(buf))) < 0) {
  401. #ifdef DEBUG
  402.         if (_res.options & RES_DEBUG)
  403.             printf("res_search failed\n");
  404. #endif
  405.         if (errno == ECONNREFUSED)
  406.             return (_gethtbyname(name));
  407.         else
  408.             return (NULL);
  409.     }
  410.     return (getanswer(&buf, n, name, C_IN, T_A));
  411. }
  412.  
  413. struct hostent *
  414. gethostbyaddr(addr, len, type)
  415.     const char *addr;
  416.     int len, type;
  417. {
  418.     int n;
  419.     querybuf buf;
  420.     register struct hostent *hp;
  421.     char qbuf[MAXDNAME+1];
  422. #ifdef SUNSECURITY
  423.     register struct hostent *rhp;
  424.     char **haddr;
  425.     u_long old_options;
  426. #endif /*SUNSECURITY*/
  427.     extern struct hostent *_gethtbyaddr();
  428.     
  429.     if (type != AF_INET)
  430.         return (NULL);
  431.     (void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
  432.         ((unsigned)addr[3] & 0xff),
  433.         ((unsigned)addr[2] & 0xff),
  434.         ((unsigned)addr[1] & 0xff),
  435.         ((unsigned)addr[0] & 0xff));
  436.     n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf);
  437.     if (n < 0) {
  438. #ifdef DEBUG
  439.         if (_res.options & RES_DEBUG)
  440.             printf("res_query failed\n");
  441. #endif
  442.         if (errno == ECONNREFUSED)
  443.             return (_gethtbyaddr(addr, len, type));
  444.         return (NULL);
  445.     }
  446.     if (!(hp = getanswer(&buf, n, qbuf, C_IN, T_PTR)))
  447.         return (NULL);
  448. #ifdef SUNSECURITY
  449.     /*
  450.      * turn off search as the name should be absolute,
  451.      * 'localhost' should be matched by defnames
  452.      */
  453.     old_options = _res.options;
  454.     _res.options &= ~RES_DNSRCH;
  455.     _res.options |= RES_DEFNAMES;
  456.     if (!(rhp = gethostbyname(hp->h_name))) {
  457.         syslog(LOG_NOTICE|LOG_AUTH,
  458.                "gethostbyaddr: No A record for %s (verifying [%s])",
  459.                hp->h_name, inet_ntoa(*((struct in_addr *)addr)));
  460.         _res.options = old_options;
  461.         return (NULL);
  462.     }
  463.     _res.options = old_options;
  464.     for (haddr = rhp->h_addr_list; *haddr; haddr++)
  465.         if (!memcmp(*haddr, addr, INADDRSZ))
  466.             break;
  467.     if (!*haddr) {
  468.         syslog(LOG_NOTICE|LOG_AUTH,
  469.                "gethostbyaddr: A record of %s != PTR record [%s]",
  470.                hp->h_name, inet_ntoa(*((struct in_addr *)addr)));
  471.         h_errno = HOST_NOT_FOUND;
  472.         return (NULL);
  473.     }
  474. #endif /*SUNSECURITY*/
  475.     hp->h_addrtype = type;
  476.     hp->h_length = len;
  477.     h_addr_ptrs[0] = (char *)&host_addr;
  478.     h_addr_ptrs[1] = NULL;
  479.     host_addr = *(struct in_addr *)addr;
  480. #if BSD < 43 && !defined(h_addr)    /* new-style hostent structure */
  481.     hp->h_addr = h_addr_ptrs[0];
  482. #endif
  483.     return (hp);
  484. }
  485.  
  486. void
  487. _sethtent(f)
  488.     int f;
  489. {
  490.     if (!hostf)
  491.         hostf = fopen(_PATH_HOSTS, "r" );
  492.     else
  493.         rewind(hostf);
  494.     stayopen = f;
  495. }
  496.  
  497. void
  498. _endhtent()
  499. {
  500.     if (hostf && !stayopen) {
  501.         (void) fclose(hostf);
  502.         hostf = NULL;
  503.     }
  504. }
  505.  
  506. struct hostent *
  507. _gethtent()
  508. {
  509.     char *p;
  510.     register char *cp, **q;
  511.  
  512.     if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" )))
  513.         return (NULL);
  514. again:
  515.     if (!(p = fgets(hostbuf, sizeof hostbuf, hostf)))
  516.         return (NULL);
  517.     if (*p == '#')
  518.         goto again;
  519.     if (!(cp = strpbrk(p, "#\n")))
  520.         goto again;
  521.     *cp = '\0';
  522.     if (!(cp = strpbrk(p, " \t")))
  523.         goto again;
  524.     *cp++ = '\0';
  525.     /* THIS STUFF IS INTERNET SPECIFIC */
  526.     if (!inet_aton(p, &host_addr))
  527.         goto again;
  528.     h_addr_ptrs[0] = (char *)&host_addr;
  529.     h_addr_ptrs[1] = NULL;
  530. #if BSD >= 43 || defined(h_addr)    /* new-style hostent structure */
  531.     host.h_addr_list = h_addr_ptrs;
  532. #else
  533.     host.h_addr = h_addr_ptrs[0];
  534. #endif
  535.     host.h_length = INT32SZ;
  536.     host.h_addrtype = AF_INET;
  537.     while (*cp == ' ' || *cp == '\t')
  538.         cp++;
  539.     host.h_name = cp;
  540.     q = host.h_aliases = host_aliases;
  541.     if (cp = strpbrk(cp, " \t"))
  542.         *cp++ = '\0';
  543.     while (cp && *cp) {
  544.         if (*cp == ' ' || *cp == '\t') {
  545.             cp++;
  546.             continue;
  547.         }
  548.         if (q < &host_aliases[MAXALIASES - 1])
  549.             *q++ = cp;
  550.         if (cp = strpbrk(cp, " \t"))
  551.             *cp++ = '\0';
  552.     }
  553.     *q = NULL;
  554.     return (&host);
  555. }
  556.  
  557. struct hostent *
  558. _gethtbyname(name)
  559.     char *name;
  560. {
  561.     register struct hostent *p;
  562.     register char **cp;
  563.     
  564.     _sethtent(0);
  565.     while (p = _gethtent()) {
  566.         if (strcasecmp(p->h_name, name) == 0)
  567.             break;
  568.         for (cp = p->h_aliases; *cp != 0; cp++)
  569.             if (strcasecmp(*cp, name) == 0)
  570.                 goto found;
  571.     }
  572. found:
  573.     _endhtent();
  574.     return (p);
  575. }
  576.  
  577. struct hostent *
  578. _gethtbyaddr(addr, len, type)
  579.     const char *addr;
  580.     int len, type;
  581. {
  582.     register struct hostent *p;
  583.  
  584.     _sethtent(0);
  585.     while (p = _gethtent())
  586.         if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len))
  587.             break;
  588.     _endhtent();
  589.     return (p);
  590. }
  591.  
  592. #ifdef RESOLVSORT
  593. static void
  594. addrsort(ap, num)
  595.     char **ap;
  596.     int num;
  597. {
  598.     int i, j;
  599.     char **p;
  600.     short aval[MAXADDRS];
  601.     int needsort = 0;
  602.  
  603.     p = ap;
  604.     for (i = 0; i < num; i++, p++) {
  605.         for (j = 0 ; j < _res.nsort; j++)
  606.         if (_res.sort_list[j].addr.s_addr == 
  607.             (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))
  608.             break;
  609.         aval[i] = j;
  610.         if (needsort == 0 && i > 0 && j < aval[i-1])
  611.         needsort = i;
  612.     }
  613.     if (!needsort)
  614.         return;
  615.  
  616.     while (needsort < num) {
  617.         for (j = needsort - 1; j >= 0; j--) {
  618.         if (aval[j] > aval[j+1]) {
  619.             char *hp;
  620.  
  621.             i = aval[j];
  622.             aval[j] = aval[j+1];
  623.             aval[j+1] = i;
  624.  
  625.             hp = ap[j];
  626.             ap[j] = ap[j+1];
  627.             ap[j+1] = hp;
  628.  
  629.         } else
  630.             break;
  631.         }
  632.         needsort++;
  633.     }
  634. }
  635. #endif
  636.  
  637. #if defined(BSD43_BSD43_NFS) || defined(sun)
  638. /* some libc's out there are bound internally to these names (UMIPS) */
  639. void
  640. ht_sethostent(stayopen)
  641.     int stayopen;
  642. {
  643.     _sethtent(stayopen);
  644. }
  645.  
  646. void
  647. ht_endhostent()
  648. {
  649.     _endhtent();
  650. }
  651.  
  652. struct hostent *
  653. ht_gethostbyname(name)
  654.     char *name;
  655. {
  656.     return (_gethtbyname(name));
  657. }
  658.  
  659. struct hostent *
  660. ht_gethostbyaddr(addr, len, type)
  661.     const char *addr;
  662.     int len, type;
  663. {
  664.     return (_gethtbyaddr(addr, len, type));
  665. }
  666.  
  667. struct hostent *
  668. gethostent()
  669. {
  670.     return (_gethtent());
  671. }
  672.  
  673. void
  674. dns_service()
  675. {
  676.     return;
  677. }
  678.  
  679. #undef dn_skipname
  680. dn_skipname(comp_dn, eom)
  681.     const u_char *comp_dn, *eom;
  682. {
  683.     return (__dn_skipname(comp_dn, eom));
  684. }
  685. #endif /*old-style libc with yp junk in it*/
  686.  
  687. #ifdef ultrix
  688. /* more icky libc packaging in ultrix */
  689. int
  690. local_hostname_length(hostname)
  691.     const char *hostname;
  692. {
  693.     int len_host, len_domain;
  694.  
  695.     if (!*_res.defdname)
  696.         res_init();
  697.     len_host = strlen(hostname);
  698.     len_domain = strlen(_res.defdname);
  699.     if (len_host > len_domain &&
  700.         !strcasecmp(hostname + len_host - len_domain, _res.defdname) &&
  701.         hostname[len_host - len_domain - 1] == '.')
  702.         return (len_host - len_domain - 1);
  703.     return (0);
  704. }
  705. #endif
  706.